import random
import struct
import hashlib
from . import tlv_builder
# import tlv_builder


class TlvBuilderHw(tlv_builder.TlvBuilder):
    def __init__(self, data={}):
        data["ver"] = 2
        tlv_builder.TlvBuilder.__init__(self, data)
        self.tlv_secret = data.get("secret", "")

    def change_attr(self, data={}):
        data["ver"] = 2
        self.change_attr(data)
        self.tlv_secret = data.get("secret", self.tlv_secret)

    def attr_print(self):
        print_str = "ver:%s\ntype:%s\npap_chap:%s\nrsvd:%s\nserial_no:%s\nreq_id:%s\nuser_ip:%s\nuser_port:%s\nerr_code:%s\nattr:%s\nsecret:%s"
        print(print_str % (
            self.tlv_ver, self.tlv_type, self.tlv_pap_chap, self.tlv_rsvd, self.tlv_serial_no, self.tlv_req_id,
            self.tlv_user_ip, self.tlv_user_port, self.tlv_err_code, self.tlv_attr,
            self.tlv_secret))

    def build_data(self):
        auth = self.__create_auth()
        result = self.__create_data(auth)
        return result

    def __create_auth(self):
        fmt = self.__create_auth_fmt()
        data = self.__create_auth_value_list()
        auth = self.__create_md5_auth(struct.pack(fmt, *data))
        return auth

    def __create_auth_fmt(self):
        auth_fmt = self.fmt_head + "QQ"
        for i in self.tlv_attr:
            auth_fmt += "BB%ss" % str(len(self.tlv_attr[i].encode("utf-8")))
        auth_fmt += "%ss" % str(len(self.tlv_secret))
        return auth_fmt

    def __create_auth_value_list(self):
        auth_value_list = self.value_list_head.copy()
        auth_value_list.append(0)
        auth_value_list.append(0)
        for i in self.tlv_attr:
            if i == "username":
                auth_value_list.append(1)
            elif i == "password":
                auth_value_list.append(2)
            elif i == "challenge":
                auth_value_list.append(3)
            elif i == "chappassword":
                auth_value_list.append(4)
            auth_value_list.append(len(self.tlv_attr[i].encode("utf-8")) + 2)
            auth_value_list.append(self.tlv_attr[i].encode("utf-8"))
        auth_value_list.append(self.tlv_secret.encode("utf-8"))
        return auth_value_list

    def __create_md5_auth(self, data):
        m = hashlib.md5()
        m.update(data)
        return m.digest()

    def __create_data(self, auth):
        fmt = self.__create_data_fmt()
        data = self.__create_data_value_list(auth)
        result = struct.pack(fmt, *data)
        return result

    def __create_data_fmt(self):
        data_fmt = self.fmt_head + "16s"
        for i in self.tlv_attr:
            data_fmt += "BB%ss" % str(len(self.tlv_attr[i].encode("utf-8")))
        return data_fmt

    def __create_data_value_list(self, auth):
        data_value_list = self.value_list_head.copy()
        data_value_list.append(auth)
        for i in self.tlv_attr:
            if i == "username":
                data_value_list.append(1)
            elif i == "password":
                data_value_list.append(2)
            elif i == "challenge":
                data_value_list.append(3)
            elif i == "chappassword":
                data_value_list.append(4)
            data_value_list.append(len(self.tlv_attr[i].encode("utf-8")) + 2)
            data_value_list.append(self.tlv_attr[i].encode("utf-8"))
        return data_value_list


if __name__ == "__main__":
    data = {"type": 3, "serial_no": 22080, "user_ip": "192.168.1.190",
            "attr": {"username": "zyt", "password": "123456"}, "secret": "123456789"}
    # data["username"] = "zyt"
    # data["pwd"] = "123456"
    # secret = "123456789"
    # print(TlvParse().get_online_data(data, secret))
    # tb = TlvBuilder()
    # tb.attr_print()
    # a = {"username": "zyt", "pwd": "123456"}
    # data = {"attr": a, "secret": "123456"}
    tb = TlvBuilderHw(data)
    # tb.attr_print()
    print(tb.build_data())
    # tb.test(*data)
